#include "key.h"
#include "sm2.h"
#include "common_func.h"
#include "core_time.h"
#include <string.h>

uint32_t write_key(uint32_t type, uint32_t index, uint8_t *pin, ECCrefPrivateKey *prikey, ECCrefPublicKey *pubkey, uint8_t *sm4_key)
{
	uint32_t pin_1_temp = 0;
	uint32_t pin_2_temp = 0;
	
	RegWrite(KEY_TYPE, type);
	RegWrite(KEY_INDEX, index);
	RegWrite(KEY_MODE, KEY_MODE_WRITE);//写入
	
	memcpy(&pin_1_temp, pin, 4);
	memcpy(&pin_2_temp, pin + 4, 4);
	RegWrite(KEY_PIN_0, pin_1_temp);
	RegWrite(KEY_PIN_1, pin_2_temp);
	
	//sm2
	if(type == 0)
	{
		RegWrite(KEY_3_IN_0, prikey->K[0]);
		RegWrite(KEY_3_IN_1, prikey->K[1]);
		RegWrite(KEY_3_IN_2, prikey->K[2]);
		RegWrite(KEY_3_IN_3, prikey->K[3]);
		RegWrite(KEY_3_IN_4, prikey->K[4]);
		RegWrite(KEY_3_IN_5, prikey->K[5]);
		RegWrite(KEY_3_IN_6, prikey->K[6]);
		RegWrite(KEY_3_IN_7, prikey->K[7]);
		RegWrite(KEY_1_IN_0, pubkey->x[0]);
		RegWrite(KEY_1_IN_1, pubkey->x[1]);
		RegWrite(KEY_1_IN_2, pubkey->x[2]);
		RegWrite(KEY_1_IN_3, pubkey->x[3]);
		RegWrite(KEY_1_IN_4, pubkey->x[4]);
		RegWrite(KEY_1_IN_5, pubkey->x[5]);
		RegWrite(KEY_1_IN_6, pubkey->x[6]);
		RegWrite(KEY_1_IN_7, pubkey->x[7]);
		RegWrite(KEY_2_IN_0, pubkey->y[0]);
		RegWrite(KEY_2_IN_1, pubkey->y[1]);
		RegWrite(KEY_2_IN_2, pubkey->y[2]);
		RegWrite(KEY_2_IN_3, pubkey->y[3]);
		RegWrite(KEY_2_IN_4, pubkey->y[4]);
		RegWrite(KEY_2_IN_5, pubkey->y[5]);
		RegWrite(KEY_2_IN_6, pubkey->y[6]);
		RegWrite(KEY_2_IN_7, pubkey->y[7]);
	}
	//sm4
	else if(type == 1)
	{
		uint32_t user_key[4];
		memcpy(user_key, sm4_key, 16);
		RegWrite(KEY_1_IN_4, user_key[0]);
		RegWrite(KEY_1_IN_5, user_key[1]);
		RegWrite(KEY_1_IN_6, user_key[2]);
		RegWrite(KEY_1_IN_7, user_key[3]);
	}
	
	RegWrite(KEY_IN_VALID, 0x1);
	
	//wait result
	while(RegRead(KEY_READY) == 0x0)
	{
		delay_ms(KEY_WAIT_TIME);
	}
	
	uint32_t err_code = RegRead(KEY_STATE);
	
	if(err_code == 0x1)
	{
		return 0x51;
	}
	else if(err_code == 0x2)
	{
		return 0x52;
	}
	else if(err_code == 0x3)
	{
		return 0x53;
	}
	
	return 0;
}

uint32_t delete_key(uint32_t type, uint32_t index, uint8_t *pin)
{
	uint32_t pin_1_temp = 0;
	uint32_t pin_2_temp = 0;
	
	RegWrite(KEY_TYPE, type);
	RegWrite(KEY_INDEX, index);
	RegWrite(KEY_MODE, KEY_MODE_DELETE);//清除
	
	memcpy(&pin_1_temp, pin, 4);
	memcpy(&pin_2_temp, pin + 4, 4);
	RegWrite(KEY_PIN_0, pin_1_temp);
	RegWrite(KEY_PIN_1, pin_2_temp);
	
	RegWrite(KEY_IN_VALID, 0x1);
	
	
	//wait result
	while(RegRead(KEY_READY) == 0x0)
	{
		delay_ms(KEY_WAIT_TIME);
	}
	
	uint32_t err_code = RegRead(KEY_STATE);
	
	if(err_code == 0x1)
	{
		return 0x51;
	}
	else if(err_code == 0x2)
	{
		return 0x52;
	}
	else if(err_code == 0x3)
	{
		return 0x53;
	}
	
	return 0;
}

//测试用，会读出密钥，实际使用时的硬件不允许读出
uint32_t access_key_test(uint32_t type, uint32_t index, uint8_t *pin, ECCrefPrivateKey *prikey, ECCrefPublicKey *pubkey, uint8_t *sm4_key)
{
	uint32_t pin_1_temp = 0;
	uint32_t pin_2_temp = 0;
	
	RegWrite(KEY_TYPE, type);
	RegWrite(KEY_INDEX, index);
	RegWrite(KEY_MODE, KEY_MODE_READ);//读出
	
	memcpy(&pin_1_temp, pin, 4);
	memcpy(&pin_2_temp, pin + 4, 4);
	RegWrite(KEY_PIN_0, pin_1_temp);
	RegWrite(KEY_PIN_1, pin_2_temp);
	
	RegWrite(KEY_IN_VALID, 0x1);
	
	
	//wait result
	while(RegRead(KEY_READY) == 0x0)
	{
		delay_ms(KEY_WAIT_TIME);
	}
	
	uint32_t err_code = RegRead(KEY_STATE);
	
	if(err_code == 0x1)
	{
		return 0x51;
	}
	else if(err_code == 0x2)
	{
		return 0x52;
	}
	else if(err_code == 0x3)
	{
		return 0x53;
	}
	
	//sm4
	if(type == 1)
	{
		
		sm4_key[0] = RegRead(KEY_1_OUT_0);
		sm4_key[1] = RegRead(KEY_1_OUT_1);
		sm4_key[2] = RegRead(KEY_1_OUT_2);
		sm4_key[3] = RegRead(KEY_1_OUT_3);
	}
	//sm2
	else if(type == 0)
	{
		prikey->K[0] = RegRead(KEY_3_OUT_0);
		prikey->K[1] = RegRead(KEY_3_OUT_1);
		prikey->K[2] = RegRead(KEY_3_OUT_2);
		prikey->K[3] = RegRead(KEY_3_OUT_3);
		prikey->K[4] = RegRead(KEY_3_OUT_4);
		prikey->K[5] = RegRead(KEY_3_OUT_5);
		prikey->K[6] = RegRead(KEY_3_OUT_6);
		prikey->K[7] = RegRead(KEY_3_OUT_7);
		pubkey->x[0] = RegRead(KEY_1_OUT_0);
		pubkey->x[1] = RegRead(KEY_1_OUT_1);
		pubkey->x[2] = RegRead(KEY_1_OUT_2);
		pubkey->x[3] = RegRead(KEY_1_OUT_3);
		pubkey->x[4] = RegRead(KEY_1_OUT_4);
		pubkey->x[5] = RegRead(KEY_1_OUT_5);
		pubkey->x[6] = RegRead(KEY_1_OUT_6);
		pubkey->x[7] = RegRead(KEY_1_OUT_7);
		pubkey->y[0] = RegRead(KEY_2_OUT_0);
		pubkey->y[1] = RegRead(KEY_2_OUT_1);
		pubkey->y[2] = RegRead(KEY_2_OUT_2);
		pubkey->y[3] = RegRead(KEY_2_OUT_3);
		pubkey->y[4] = RegRead(KEY_2_OUT_4);
		pubkey->y[5] = RegRead(KEY_2_OUT_5);
		pubkey->y[6] = RegRead(KEY_2_OUT_6);
		pubkey->y[7] = RegRead(KEY_2_OUT_7);
	}
	
	return 0;
}


//仅获得权限
uint32_t access_key(uint32_t type, uint32_t index, uint8_t *pin)
{
	uint32_t pin_1_temp = 0;
	uint32_t pin_2_temp = 0;
	
	RegWrite(KEY_USE_INT_KEY, 0x01);
	RegWrite(KEY_TYPE, type);
	RegWrite(KEY_INDEX, index);
	RegWrite(KEY_MODE, KEY_MODE_READ);//读出
	
	memcpy(&pin_1_temp, pin, 4);
	memcpy(&pin_2_temp, pin + 4, 4);
	RegWrite(KEY_PIN_0, pin_1_temp);
	RegWrite(KEY_PIN_1, pin_2_temp);
	
	RegWrite(KEY_IN_VALID, 0x1);
	
	
	//wait result
	while(RegRead(KEY_READY) == 0x0)
	{
		delay_ms(KEY_WAIT_TIME);
	}
	
	uint32_t err_code = RegRead(KEY_STATE);
	
	if(err_code == 0x1)
	{
		return 0x51;
	}
	else if(err_code == 0x2)
	{
		return 0x52;
	}
	else if(err_code == 0x3)
	{
		return 0x53;
	}
	
	return 0;
}


uint32_t release_key(uint32_t type, uint32_t index)
{
	RegWrite(KEY_TYPE, type);
	RegWrite(KEY_INDEX, index);
	RegWrite(KEY_MODE, KEY_MODE_RELEASE);//读出
	RegWrite(KEY_IN_VALID, 0x1);
	RegWrite(KEY_USE_INT_KEY, 0x00);
	
	//wait result
	while(RegRead(KEY_READY) == 0x0)
	{
		delay_ms(KEY_WAIT_TIME);
	}
	
	return 0;
}